package Principal;

import java.math.BigDecimal;
import java.util.List;

public class EventoFinalTransmissaoSucesso extends Evento{

	public EventoFinalTransmissaoSucesso(BigDecimal _tempoExecucao, Host _host, HistoriaSimulacao _historiaSimulacao, Estatistica _estatistica, List<Host> _hostsSistema) {
		super(_tempoExecucao, _host, _historiaSimulacao, _estatistica, _hostsSistema);		
	}
	

	@Override
	public void executar() {
		
		// Verifica se o modo verbose esta ativo para imprimir o evento na tela
		if(verbose){
			System.out.printf("Evento Fim Transmissao Sucesso. Host: %d. Tempo: %s us.\n", getNumeroHost(), tempoExecucao.setScale(4, BigDecimal.ROUND_HALF_EVEN).toString());
		}
		
		// Coleta as informacoes referentes as estatisticas do tempo de acesso do quadro 
		estatistica.meioLivre(host);
		
		// Remove o quadro que estava transmitindo da fila
		host.removeQuadroFila();
		
		// Calcula estatistisca p/ final de transmissao
		estatistica.finalTransmissaoSucesso(host);
		
		//host 1 coleta o tempo de meio  para calculo da utilizacao
		// quando e ele que transmitiu os dados
		if(getNumeroHost() == 1)
		{
			//System.out.printf("Host 1 final transmissao. Tempo: %s us.\n", tempoExecucao.setScale(4, BigDecimal.ROUND_HALF_EVEN).toString());
			
			estatistica.finalMeioOcupado(host);
		}
		
		// Indica que parou de transmitir
		host.setNaoTransmitindo();
		host.resetStatusMeio();
		host.setMeioLivre();
		
		// Faz Reset no Binary backoff
		host.resetBackoff();
		
		// Caso ainda tenha pacotes a transmitir 
		// Aguarda o tempo de espera
		host.setTempoUltimaTransmissaoSistema(tempoExecucao);
		
		// Incrementa o Numero de quadros transmitidos com sucesso
		host.incrementaQuadroTxSucesso();
		
		//Verifica o fim da rodada para calculo das estatisticas
		estatistica.incrementaNumeroMensagensEnviadasSistema(host);
		estatistica.verificaFimRodada();
		
		// Verifica se a fila de espera ainda possui pacotes
		if (!host.isFilaVazia()){			
			//adiciona novo evento de inicio de transmissao
			BigDecimal tempoTransmissao = tempoExecucao.add(host.getTempoEspera(tempoExecucao));
			Evento inicioTx = new EventoInicioTransmissao(tempoTransmissao, host, historiaSimulacao, estatistica, hostsSistema);
			historiaSimulacao.adicionarEvento(inicioTx);
			
			
 		} 	
				
		// Gera Eventos de meio livre de acordo com o atraso de propagacao
		// para todos os demais hosts
		for (Host hostMeioLivre : hostsSistema) 
		{		
			if(!hostMeioLivre.equals(host)){				
				BigDecimal tempoEvento = tempoExecucao.add(hostMeioLivre.getAtrasoPropagacao()).add(host.getAtrasoPropagacao());
				Evento meioLivre = new EventoMeioLivre(tempoEvento , hostMeioLivre, historiaSimulacao, estatistica, hostsSistema);
				//hostMeioLivre.setTempoUltimaTransmissaoSistema(tempoExecucao);
				historiaSimulacao.adicionarEvento(meioLivre);
			}
		}
	}

}
